package com.junzhiit.nengji.api.web.util;

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.multipart.MultipartFile;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class FileUtil {
	
	private final static Log logger = LogFactory.getLog(FileUtil.class);
	
	private final static int QR_CODE_WIDTH = 430;
	
	private final static int QR_CODE_HEIGHT = 430;
	
	public final static String QR_CODE_FORMAT = "png";

	public static String upload(MultipartFile file, String uploadPath) {
		if (file == null || file.isEmpty()) {
			return null;
		} else {
			File fileFolder = new File(uploadPath);

			if (!fileFolder.exists()) {
				fileFolder.mkdirs();
			}

			String fileName = "";
			InputStream is = null;
			try {
				String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
				fileName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;
				is = file.getInputStream();
				FileUtils.copyInputStreamToFile(is, new File(uploadPath + fileName));
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			} finally {
				ReleaseResourceUtil.closeInputStream(is);
			}
			return fileName;
		}
	}
	
	public static boolean moveFile(String sourceFilePath, String targetPath){
		boolean isSucceed = true;
		try {
			File src = new File(sourceFilePath);
			File destDir = new File(targetPath);
			if(src.isDirectory()){
				FileUtils.moveDirectoryToDirectory(src, destDir, true);
			} else if(src.isFile()){
				FileUtils.moveFileToDirectory(src, destDir, true);
			}
		} catch (Exception e) {
			isSucceed = false;
			logger.error(e.getMessage(), e);
		}
		return isSucceed;
	}
	
	public static boolean removeFile(String filefullPath){
		boolean isSucceed = true;
		try {
			File targetFile = new File(filefullPath); 
	        if (targetFile.isDirectory()){
	        	FileUtils.deleteDirectory(targetFile);
	        } else if (targetFile.isFile()) {
	        	targetFile.delete(); 
	        }
		} catch (Exception e) {
			isSucceed = false;
			logger.error(e.getMessage(), e);
		} 
		return isSucceed;
	}

	public static void download(HttpServletRequest request,HttpServletResponse response,
			String filefullPath){
		String fileName = filefullPath.substring(filefullPath.lastIndexOf("/") + 1, filefullPath.length());
		download(request, response, filefullPath, fileName);
	}
	
	public static void download(HttpServletRequest request,HttpServletResponse response,
			String path,String fileName){
		BufferedInputStream bis = null;  
        BufferedOutputStream bos = null;
		try {
			//Dealing with the browser's code
			String userAgent = request.getHeader("User-Agent");
			byte[] bytes = userAgent.contains("MSIE") ? fileName.getBytes() : fileName.getBytes("UTF-8");
			fileName = new String(bytes, "ISO-8859-1");
			long fileLength = new File(path).length();
	        response.setContentType("octets/stream");
	        response.addHeader("Content-Type", "text/html; charset=utf-8");
	        response.setHeader("Content-disposition", "attachment; filename="
	                + fileName);
	        response.setHeader("Content-Length", String.valueOf(fileLength));
	        
			bis = new BufferedInputStream(new FileInputStream(path));
			bos = new BufferedOutputStream(response.getOutputStream());  
	        byte[] buff = new byte[2048];  
	        int bytesRead;  
	        while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {  
	            bos.write(buff, 0, bytesRead);  
	        }
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage() , e);
		} finally {
			ReleaseResourceUtil.closeBufferedInputStream(bis);
			ReleaseResourceUtil.closeOutputStream(bos);
		}
	}
	
	public static void createQRCode(String content,String fullpath){
		Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        hints.put(EncodeHintType.CHARACTER_SET, Constants.UTF8);
        File file = new File(fullpath);
    	try {
    		if (!file.exists()) {
    			file.mkdirs();
			}
    		
    		BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,
        			QR_CODE_WIDTH, QR_CODE_HEIGHT, hints);
			MatrixToImageWriter.writeToFile(matrix, QR_CODE_FORMAT, file);
			logger.info("Created a QR Code to succeed.");
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}
	
	public static void qrCodePoster(QRCodePoster cp){
		try {
			BufferedImage buffImg = ImageIO.read(new File(cp.getBgPath()));
	        BufferedImage waterImg = ImageIO.read(new File(cp.getCodePath()));
	        Graphics2D g2d = buffImg.createGraphics();
	        File file = new File(cp.getTargetPath());
	        if (!file.exists()) {
    			file.mkdirs();
			}
	        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f));
	        g2d.drawImage(waterImg, cp.getX().intValue(), cp.getY().intValue(),
	        		cp.getQrCodeSize().intValue(), cp.getQrCodeSize().intValue(), null);
	        
	        ImageIO.write(buffImg, "jpeg", file);
	        g2d.dispose();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static boolean exists(String filePath){
		File fileFolder = new File(filePath);
		return fileFolder.exists();
	}
}
